home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / think / AmigaGnuChess.lha / chess / src.lha / src / amiga / amiterm.c < prev    next >
C/C++ Source or Header  |  1992-09-06  |  13KB  |  664 lines

  1. /*
  2.  * Amiga curses-style terminal routines.
  3.  * Taken from Amiga ISpell, and hacked to fit GNUCHESS.
  4.  *
  5.  * (C) 1992 Martin W. Scott.
  6.  */
  7. #include <exec/types.h>
  8. #include <exec/memory.h>
  9. #include <intuition/intuition.h>
  10. #include <libraries/gadtools.h>
  11. #include <dos/dos.h>
  12. #include <proto/exec.h>
  13. #include <proto/dos.h>
  14. #include <proto/gadtools.h>
  15. #include <proto/intuition.h>
  16.  
  17. #include <stdio.h>
  18. #include <fcntl.h>
  19. #include <stdarg.h>
  20. #include <ctype.h>
  21.  
  22. #include "display.h"
  23. #include "amiterm.h"
  24. #include "draw.h"
  25. #include "pointer.h"
  26. #include "requester.h"
  27. #include "gnuchess.h"    /* for struct flag definition */
  28.  
  29. /* Prototypes for static functions */
  30. static void CloseLibs(void);
  31. static BOOL OpenLibs(void);
  32. static BOOL Open_Console(struct IOStdReq *rq, struct Window *win);
  33. static void CleanUp(void);
  34. static void putcon(struct IOStdReq *rq, char *str);
  35. static void __stdargs printc(char *fmt, ...);
  36. static void cursor_off(void);
  37. static void cursor_on(void);
  38. static void con_set_line(int offset, int len);
  39. static void con_set_pagelen(void);
  40. static void setcolors(int color);
  41. static void DisableWindow(void);
  42. static void EnableWindow(void);
  43. static void About(void);
  44. static int mousebutton(BOOL down, WORD x, WORD y);
  45. static int menupick(WORD menu, WORD item, WORD subitem);
  46. static int getevent(struct Window *ApplWin);
  47.  
  48. /* special event 'char's */
  49. #define IGNORE_EVENT    -1
  50. #define MOUSE_MOVE    1000
  51. #define MENU_PICK    1001
  52.  
  53. /* libraries */
  54. struct IntuitionBase *IntuitionBase;
  55. struct GadToolsBase *GadToolsBase;
  56. struct GfxBase *GfxBase;
  57. struct Library *ReqToolsBase;
  58.  
  59. /* storage */
  60. static char movestr[6];        /* mousebutton move */
  61. static char *menuchoice;    /* menu => command */
  62. struct RastPort *rp;
  63. static struct IOStdReq *scr_rq = NULL;
  64. static int get_file;        /* next string from filereq */
  65. static char *frhail;        /* hail-text for filereq */
  66. int get_command;        /* use mouse/menus for input */
  67. static char colorfile[100];    /* name of color file */
  68.  
  69.  
  70. /* close libraries that were opened */
  71. static void
  72. CloseLibs()
  73. {
  74.     if (ReqToolsBase) CloseLibrary(ReqToolsBase);
  75.     if (GadToolsBase) CloseLibrary(GadToolsBase);
  76.     if (GfxBase) CloseLibrary(GfxBase);
  77.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  78. }
  79.  
  80. /* open required libraries */
  81. static BOOL
  82. OpenLibs()
  83. {
  84.     if ((IntuitionBase = (void *)OpenLibrary("intuition.library",37L)) &&
  85.         (GfxBase = OpenLibrary("graphics.library", 37L)) &&
  86.         (GadToolsBase =  (void *)OpenLibrary("gadtools.library",37L)))
  87.     {
  88.         ReqToolsBase = (void *)OpenLibrary("reqtools.library", 37L);
  89.         return TRUE;
  90.     }
  91.  
  92.     CloseLibs();
  93.     return FALSE;
  94. }
  95.  
  96. static BOOL
  97. Open_Console(struct IOStdReq *rq, struct Window *win)
  98. {
  99.     rq->io_Data = (APTR) win;
  100.     rq->io_Length = sizeof(struct IOStdReq);
  101.     if (OpenDevice("console.device",0,rq,0))
  102.       return(FALSE);    /* could not get device */      
  103.     return(TRUE);    /* device opened successfully */
  104. }
  105.  
  106. static void
  107. CleanUp()
  108. {
  109.     if (scr_rq)
  110.     {
  111.         if (scr_rq->io_Device) CloseDevice(scr_rq);
  112.         FreeMem(scr_rq, sizeof(struct IOStdReq));
  113.         scr_rq = NULL;
  114.     }
  115.     CloseChessWindow();
  116.     CloseDownScreen();
  117.     CloseLibs();
  118. }
  119.  
  120. void
  121. endwin()
  122. {
  123.     CleanUp();
  124. }
  125.  
  126. int
  127. initscr()
  128. {
  129.     if (!OpenLibs())
  130.         return FALSE;
  131.  
  132.     if (!(scr_rq = AllocMem(sizeof(struct IOStdReq), MEMF_PUBLIC | MEMF_CLEAR)))
  133.     {
  134.         CloseLibs();
  135.         return FALSE;
  136.     }
  137.  
  138.     strcpy(colorfile, libdir);
  139.     AddPart(colorfile, "gnuchess.colors", sizeof(colorfile));
  140.     LoadColors(colorfile);    /* may fail...who cares? */
  141.  
  142.     if ((SetupScreen() == 0) &&
  143.         (OpenChessWindow() == 0) &&
  144.         (Open_Console(scr_rq, ChessWnd)))
  145.     {
  146.         rp = ChessWnd->RPort;
  147.         return TRUE;
  148.     }
  149.     CleanUp();
  150.     return FALSE;
  151.  
  152. } /* initscr */
  153.  
  154.  
  155. /********************************************************************************/
  156. /*    Buffered output routines                        */
  157. /********************************************************************************/
  158.  
  159. #define CONBUFSIZ    128
  160.  
  161. static char putbuf[CONBUFSIZ+1];
  162. static UWORD bufpos;
  163.  
  164. #define putch(ch)    {if (bufpos == CONBUFSIZ) refresh(); putbuf[bufpos++] = (ch);}
  165. #define inst_putch(ch)    putch(ch); refresh()
  166.  
  167. void
  168. refresh()
  169. {
  170.     putbuf[bufpos]='\0';
  171.     putcon(scr_rq, putbuf);
  172.     bufpos=0;
  173.     chkabort();
  174. }
  175.  
  176. void
  177. putstr(char *str)
  178. {
  179.     if (strlen(str) >= (CONBUFSIZ-bufpos))
  180.         refresh();
  181.     while (*str)
  182.         putch(*str++);
  183. }
  184.  
  185. /*******************************************************************************/
  186.  
  187. static void
  188. putcon(struct IOStdReq *rq, char *str)
  189. {
  190.     /* in case the console has not been initialized */
  191.     if ( rq == NULL ) {
  192.         fprintf(stdout,"%s",str);
  193.     return;
  194.     }
  195.     rq->io_Command = CMD_WRITE;
  196.     rq->io_Data = (APTR) str;
  197.     rq->io_Length = -1;    
  198.     DoIO(rq);    
  199. }
  200.  
  201. static void __stdargs
  202. printc(char *fmt, ...)
  203. {
  204.     va_list ap;
  205.     char    pbuff[256];
  206.     va_start(ap,fmt);
  207.     vsprintf(pbuff,fmt,ap);
  208.     putstr(pbuff);
  209. }
  210.  
  211. static void
  212. cursor_off()
  213. {
  214.      printc("%c%c%c%c",0x9b,0x30,0x20,0x70);
  215. }
  216.  
  217. static void
  218. cursor_on()
  219. {
  220.     printc("%c%c%c",0x9b,0x20,0x70);
  221. }
  222.  
  223. static void
  224. con_set_line(int offset,int len)
  225. {
  226.     char buf[10];
  227.     sprintf(buf,"%d",(short)offset);
  228.     printc("%c%s%c",0x9b,buf,0x78);
  229.  
  230.     sprintf(buf,"%d",(short)len);
  231.     printc("%c%s%c",0x9b,buf,0x75);
  232. }
  233.  
  234. static void
  235. con_set_pagelen()
  236. {
  237.     printc("%c%c",0x9b,0x74);
  238. }
  239.  
  240. static void
  241. setcolors(int color)
  242. {
  243.     char buf[100];
  244.     sprintf(buf,"\x9b%dm", color);
  245.     putstr(buf);
  246. }
  247.  
  248. static void
  249. EnableWindow()
  250. {
  251.     struct MenuItem *item;
  252.  
  253.     ModifyIDCMP(ChessWnd, CHESS_IDCMP);
  254.  
  255.     /* update menu toggle status */
  256.     item = ItemAddress(ChessMenus, FULLMENUNUM(TOGGLES, REVERSE, 0));
  257.     if (flag.reverse) item->Flags |= CHECKED;
  258.     else item->Flags &= ~CHECKED;
  259.  
  260.     item = ItemAddress(ChessMenus, FULLMENUNUM(TOGGLES, COORDINATES, 0));
  261.     if (flag.coords) item->Flags |= CHECKED;
  262.     else item->Flags &= ~CHECKED;
  263.  
  264.     item = ItemAddress(ChessMenus, FULLMENUNUM(TOGGLES, THINKING, 0));
  265.     if (flag.post) item->Flags |= CHECKED;
  266.     else item->Flags &= ~CHECKED;
  267.  
  268.     item = ItemAddress(ChessMenus, FULLMENUNUM(TOGGLES, RANDOM, 0));
  269.     if (dither) item->Flags |= CHECKED;
  270.     else item->Flags &= ~CHECKED;
  271.  
  272.     item = ItemAddress(ChessMenus, FULLMENUNUM(TOGGLES, BEEP, 0));
  273.     if (flag.beep) item->Flags |= CHECKED;
  274.     else item->Flags &= ~CHECKED;
  275. /***
  276.     item = ItemAddress(ChessMenus, FULLMENUNUM(TOGGLES, USEBOOK, 0));
  277.     if (Book) item->Flags |= CHECKED;
  278.     else item->Flags &= ~CHECKED;
  279.  NOT WORKING... ***/
  280.  
  281.     SetMenuStrip(ChessWnd, ChessMenus);
  282. }
  283.  
  284. static void
  285. DisableWindow()        /* let user type ahead, but no more */
  286. {
  287.     ClearMenuStrip(ChessWnd);
  288.     ModifyIDCMP(ChessWnd, IDCMP_VANILLAKEY);
  289. }
  290.  
  291. #define ABOUT_TXT_1 "\
  292. Welcome to Amiga GnuChess Version 1.0,\n\
  293. derived from GNU Chess Version 4.00, patchlevel 58.\n\
  294. \n\
  295. GNU Chess is Copyright (c) 1986-1992 Free Software Foundation.\n\
  296. Amiga graphics display is Copyright (c) 1992 Martin W. Scott.\n\
  297. Freely redistributable, subject to the GNU General Public Licence.\n\
  298. "
  299.  
  300. #define ABOUT_TXT_2 "\
  301. You may contact the author of this Amiga port at:\n\
  302. \n\
  303.         Martin W. Scott,\n\
  304.         23, Drum Brae North,\n\
  305.         Edinburgh, EH4 8AT\n\
  306.         United Kingdom.\n\
  307. \n\
  308. This version was released in September of 1992.\n\
  309. Thanks to Nico François for reqtools.library.\
  310. "
  311.  
  312. /* EasyEasyrequest... */
  313. static void
  314. About()
  315. {
  316.     struct EasyStruct es;
  317.     char *arglist[2];
  318.  
  319.     es.es_StructSize = sizeof(struct EasyStruct);
  320.     es.es_Flags = 0L;
  321.     es.es_Title = "About Amiga GnuChess";
  322.     es.es_TextFormat = "%s%s";
  323.     es.es_GadgetFormat = "OK";
  324.     arglist[0] = ABOUT_TXT_1;
  325.     arglist[1] = ABOUT_TXT_2;
  326.     EasyRequestArgs(ChessWnd, &es, NULL, arglist);
  327. }
  328.  
  329. /* convert mouse-event to chess-square string */
  330. /* to do?: erase square and make pointer an image of the piece 'held' */
  331.  
  332. static int
  333. mousebutton(BOOL down, WORD x, WORD y)
  334. {
  335.     static UWORD    from_row, from_col;
  336.     static BOOL    have_from;
  337.     UWORD        row, col;
  338.     int        rv = -1;
  339.  
  340.     row = 7-(y-TOP_OFFSET)/SQUARE_HEIGHT;
  341.     col = (x-LEFT_OFFSET)/SQUARE_WIDTH;
  342.  
  343.     if (!have_from && down)        /* from square selected */
  344.     {
  345.         if (row < 8 && col < 8)
  346.         {
  347.             AmiToggleSquare(row,col);
  348.             from_row = row;
  349.             from_col = col;
  350.             have_from = TRUE;
  351.             SetToPointer(ChessWnd);
  352.         }
  353.          /* else ignore mouse-command */
  354.     }
  355.     else if (have_from)        /* to square selected */
  356.     {
  357.         ClrToPointer(ChessWnd);
  358.         AmiToggleSquare(from_row,from_col);    /* restore from-square */
  359.  
  360.         if ((row < 8 && col < 8) &&            /* in bounds */
  361.             (from_row != row || from_col != col))    /* aborted */
  362.         {
  363.             if (flag.reverse)    /* convert position */
  364.             {
  365.                 from_row = 7-from_row;
  366.                 from_col = 7-from_col;
  367.                 row = 7-row;
  368.                 col = 7-col;
  369.             }
  370.             sprintf(movestr, "%c%c%c%c", from_col+'a', from_row+'1',
  371.                              col+'a', row+'1');
  372.             rv = MOUSE_MOVE;
  373.         }
  374.         have_from = FALSE;
  375.     }
  376.  
  377.     return rv;
  378. }
  379.  
  380. /* convert menu choice to command strings */
  381. static int
  382. menupick(WORD menu, WORD item, WORD subitem)
  383. {
  384.     int rv = MENU_PICK;
  385.  
  386.     switch (menu)
  387.     {
  388.     case PROJECT:
  389.         switch (item)
  390.         {
  391.         case NEW_GAME:    menuchoice = "new"; break;
  392.         case LOAD_GAME: menuchoice = "get";
  393.                 frhail = "Load game...";
  394.                 get_file = TRUE;
  395.                 break;
  396.         case SAVE_GAME: menuchoice = "save";
  397.                 frhail = "Save game...";
  398.                 get_file = TRUE;
  399.                 break;
  400.         case LISTING:    menuchoice = "list"; break;
  401.         case EDITBOARD: menuchoice = "edit"; break;
  402.         case SHOWHELP:    menuchoice = "help"; break;
  403.         case QUIT:    menuchoice = "quit"; break;
  404.  
  405.         case ABOUT:    About();
  406.         default:    rv = -1;
  407.         }
  408.         break;
  409.  
  410.     case SETTINGS:
  411.         switch (item)
  412.         {
  413.         case SET_CLOCK:    menuchoice = "clock"; break;
  414.         case COLORS:    DoPalette(ChessWnd); rv = -1; break;
  415.         case SAVECOLORS: SaveColors(colorfile);
  416.         default:    rv = -1;
  417.         }
  418.         break;
  419.  
  420.     case TOGGLES:
  421.         switch (item)
  422.         {
  423.         case REVERSE:    menuchoice = "reverse"; break;
  424.         case COORDINATES: menuchoice = "coords"; break;
  425.         case THINKING:    menuchoice = "post"; break;
  426.         case RANDOM:    menuchoice = "random"; break;
  427.         case BEEP:    menuchoice = "beep"; break;
  428. /*        case USEBOOK:    menuchoice = "book"; break;*/
  429.  
  430.         default:    rv = -1;
  431.         }
  432.         break;
  433.  
  434.     case MOVE:
  435.         switch (item)
  436.         {
  437.         case GO:    menuchoice = "go"; break;
  438.         case UNDO:    menuchoice = "undo"; break;
  439.         case REMOVE:    menuchoice = "remove"; break;
  440.         case SWITCH:    menuchoice = "switch"; break;
  441.         case FORCE:    menuchoice = "force"; break;
  442.         case REDRAW:    menuchoice = "bd"; break;
  443.         case HINT:    menuchoice = "hint"; break;
  444.  
  445.         default:    rv = -1;
  446.         }
  447.         break;
  448.  
  449.     default:    rv = -1;
  450.     }
  451.  
  452.     return rv;
  453. }
  454.  
  455. /* get input from user and tokenize it */ 
  456. static int
  457. getevent(struct Window *ApplWin)
  458. {
  459.     struct IntuiMessage *mess;
  460.     int retval = IGNORE_EVENT;
  461.  
  462.     /* wait for an intuition event */
  463.     while( !(mess = (struct IntuiMessage *)GetMsg(ApplWin->UserPort)) )
  464.         Wait(1 << ApplWin->UserPort->mp_SigBit);
  465.  
  466.     switch(mess->Class) {
  467.     case IDCMP_VANILLAKEY:
  468.         retval = mess->Code;
  469.         if (isprint(retval))
  470.         inst_putch(retval);
  471.         break;
  472.     case IDCMP_MENUPICK:
  473.         retval = menupick(MENUNUM(mess->Code), ITEMNUM(mess->Code), SUBNUM(mess->Code));
  474.         break;
  475.     case IDCMP_MOUSEBUTTONS:
  476.         retval = mousebutton(mess->Code == SELECTDOWN, mess->MouseX, mess->MouseY);
  477.         break;
  478.     default:
  479.         break;
  480.     }
  481.     ReplyMsg(mess);
  482.     return(retval);
  483. }
  484.  
  485. /*
  486.  * end of amiga console support.
  487.  *-----------------------------------------------------------------------*/
  488.  
  489. void __stdargs
  490. printw(char *fmt, ...)
  491. {
  492.     va_list ap;
  493.     char    pbuff[256];
  494.     va_start(ap,fmt);
  495.     vsprintf(pbuff,fmt,ap);
  496.     putstr(pbuff);
  497. }
  498.  
  499. int __stdargs
  500. scanw(char *fmt, ...)
  501. {
  502.     va_list ap;
  503.     char    pbuf[256];
  504.     va_start(ap,fmt);
  505.     if (getstr(pbuf) != (char *)EOF)
  506.         return sscanf(pbuf, fmt, va_arg(ap,long),va_arg(ap,long),va_arg(ap,long),va_arg(ap,long),va_arg(ap,long));
  507.     else return 0;
  508. }
  509.  
  510. int
  511. getch()
  512. {
  513.     int ch;
  514.  
  515.     refresh();
  516.     while ( (ch=getevent(ChessWnd)) == -1 )
  517.         ;
  518.     return( ch );
  519. }
  520.  
  521. char *
  522. getstr(char *buf)
  523. {
  524.     int ch;
  525.     char *t = buf;
  526.  
  527.     /* last command was load/save */
  528.     if (get_file && DoFileRequest(ChessWnd, frhail, buf))
  529.     {
  530.     get_file = FALSE;
  531.     return buf;
  532.     }
  533.     /* else fall-through, let user type name... */
  534.  
  535.     get_file = FALSE;
  536.     refresh();
  537.     if (get_command)
  538.     EnableWindow();
  539.  
  540.     *buf = '\0';    /* assume nothing first */
  541.  
  542.     while ((ch=getevent(ChessWnd)) != '\r')
  543.     switch (ch)
  544.     {
  545.         case 0x0c:    /* ^L i.e. redraw */
  546.             strcpy(buf, "bd");
  547.             goto finished;
  548.             
  549.         case 0x1c:    /* ^\ i.e. EOF */
  550.             DisableWindow();
  551.             return (char *)EOF;
  552.  
  553.         case '\b':    /* backspace, delete */
  554.         case 0x7f:
  555.             if (t > buf)
  556.             {
  557.                 t--;
  558.                 printw("\b \b");
  559.                 refresh();
  560.             }
  561.             break;
  562.  
  563.         case MOUSE_MOVE:
  564.             putstr(movestr);
  565.             refresh();
  566.             strcpy(buf, movestr);
  567.             goto finished;        
  568.  
  569.         case MENU_PICK:
  570.             strcpy(buf, menuchoice);
  571.             goto finished;
  572.  
  573.         case IGNORE_EVENT:
  574.             break;
  575.  
  576.         default:
  577.             *t++ = ch;
  578.     }
  579.     *t = '\0';
  580.  
  581. finished:
  582.     DisableWindow();
  583.     return (buf);
  584. }
  585.  
  586. /* clear the screen */
  587. void
  588. clear ()
  589. {
  590.     char buf[10];
  591.     sprintf(buf,"%c",0x0c);
  592.     putstr(buf);
  593.     refresh();
  594. }
  595.  
  596. /* clear to end of line */
  597. void
  598. clrtoeol ()
  599. {
  600.     char buf[10];
  601.     sprintf(buf,"%c%c",0x9b,0x4b);
  602.     putstr(buf);
  603. }
  604.  
  605. /* move to row, col */
  606. void
  607. move (row, col)
  608. {
  609.     char buf[10];
  610.     sprintf(buf,"%c%d%c%d%c",0x9b,row+1,0x3b,col+1,0x48);
  611.     putstr(buf);
  612. }
  613.  
  614. /* do a back space */
  615. void
  616. backup ()
  617. {
  618.     inst_putch((int)'\b');
  619. }
  620.  
  621. void
  622. leaveok(void *p, int turnoff)
  623. {
  624.     if (turnoff)
  625.         cursor_off();
  626.     else
  627.         cursor_on();
  628. }
  629.  
  630. void
  631. attron(int what)
  632. {
  633.     if (what < 8)    /* color change */
  634.         setcolors(30+what);
  635. }
  636.  
  637. void
  638. standout()
  639. {
  640.     setcolors(7);
  641. }
  642.  
  643. void
  644. standend()
  645. {
  646.     setcolors(0);
  647. }
  648.  
  649. void
  650. flash()
  651. {
  652.     inst_putch(0x7);
  653. }
  654.  
  655. extern void dobeep(long);
  656. void beep()
  657. {
  658.     dobeep(100);
  659. }
  660.  
  661. /* unused at moment... */
  662. void crmode(){}
  663. void nocrmode(){}
  664.